import os
import re
import yt_dlp
import httpx
from typing import Optional
from datetime import datetime
from filter_video import FilterVideo
from tiktok_video_extractor import extract_tiktok_video

class VideoDownloader:
    def __init__(self, save_path: str = 'videos'):
        self.save_path = save_path
        self.create_save_directory()

    def create_save_directory(self):
        if not os.path.exists(self.save_path):
            os.makedirs(self.save_path)

    def get_filename(self, platform: str, custom_name: Optional[str] = None) -> str:
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        prefix = custom_name or platform
        safe_name = re.sub(r'[\\/:"*?<>|]+', '_', prefix)
        return f"{safe_name}_{timestamp}.mp4"

    async def download_video(self, url: str, custom_name: Optional[str] = None) -> Optional[str]:
        platform = FilterVideo.detect_platform(url)
        if not platform:
            print("❌ Unsupported URL/platform.")
            return None

        filename = self.get_filename(platform, custom_name)
        output_path = os.path.join(self.save_path, filename)

        # 🔹 TikTok 特殊处理（先提取直链）
        if platform == 'tiktok':
            print("🎯 Extracting TikTok real video URL...")
            real_url = await extract_tiktok_video(url)
            if not real_url or not real_url.startswith("http"):
                print("❌ Failed to extract TikTok video URL.")
                return None

            # ✅ 使用 httpx 异步下载
            try:
                headers = {
                    'User-Agent': 'Mozilla/5.0',
                    'Referer': 'https://www.tiktok.com/',
                }
                async with httpx.AsyncClient(timeout=30.0) as client:
                    response = await client.get(real_url, headers=headers)
                    response.raise_for_status()
                    with open(output_path, 'wb') as f:
                        f.write(response.content)

                print(f"✅ TikTok video saved to: {output_path}")
                return output_path
            except Exception as e:
                print(f"❌ TikTok download error: {e}")
                return None

        # 🔹 其他平台使用 yt_dlp
        ydl_opts = FilterVideo.get_ydl_options(platform, output_path)
        try:
            with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                ydl.download([url])
            print(f"✅ {platform.capitalize()} video saved to: {output_path}")
            return output_path
        except yt_dlp.utils.DownloadError as e:
            print(f"❌ yt_dlp error: {e}")
        except Exception as e:
            print(f"❌ Unexpected error: {e}")

        return None
